package com.bcdbook.activiti.security;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;

/**
 * Spring Security 工具类
 *
 * @author summer
 * @date 2018-12-29 16:17
 * @version V1.0.0-RELEASE
 */
@Component
@Slf4j
public class SecurityUtil {

    /**
     * 注入用户详情的服务接口
     */
    @Resource
    @Lazy
    private UserDetailsService userDetailsService;

    /**
     * 创建模拟登录接口
     *
     * @author summer
     * @date 2018-12-29 16:18
     * @param username 用户名
     * @return void
     * @version V1.0.0-RELEASE
     */
    public void logInAs(String username) {

        /*
         * 获取用户
         */
        // 获取用户对象
        UserDetails user = userDetailsService.loadUserByUsername(username);
        // 校验用户是否存在
        if (user == null) {
            throw new IllegalStateException("用户不存在, 用户名: " + username);
        }
        log.info("当前模拟登录用户: {}", username);

        /*
         * 配置用户到 Security Context 中
         */
        SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {
            // 获取用户的权限
            @Override
            public Collection<? extends GrantedAuthority> getAuthorities() {
                return user.getAuthorities();
            }

            // 获取用户的验证信息
            @Override
            public Object getCredentials() {
                return user.getPassword();
            }

            // 获取用户详情信息
            @Override
            public Object getDetails() {
                return user;
            }

            // 获取用户的主要信息
            @Override
            public Object getPrincipal() {
                return user;
            }

            // 用户是否验证通过
            @Override
            public boolean isAuthenticated() {
                return true;
            }

            // 用户是否已认证
            @Override
            public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
            }

            // 获取用户名
            @Override
            public String getName() {
                return user.getUsername();
            }
        }));

        // 设置用户信息到 activiti 的权限验证中
        org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
    }

    /**
     * 获取当前在线用户
     *
     * @author summer
     * @date 2019-01-04 19:06
     * @return org.springframework.security.core.userdetails.UserDetails
     * @version V1.0.0-RELEASE
     */
    public UserDetails getActiveUserDetails(){
        // 获取当前登录用户
        return  (UserDetails) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();
    }

    /**
     * 密码加密器
     *
     * @author summer
     * @date 2018-12-29 17:24
     * @return org.springframework.security.crypto.password.PasswordEncoder
     * @version V1.0.0-RELEASE
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
